const path = require('path')
const fs = require('fs-extra')
const dayjs = require('dayjs')
const execShPromise = require('exec-sh').promise
const Service = require('egg').Service

class BackupService extends Service {
  /**
   * 备份数据库
   * https://docs.mongodb.com/database-tools/mongodump/
   */
  async backupDatabase() {
    const { config } = this
    const { backupDir, mongodb, dbName } = config
    const uri = mongodb
    const time = dayjs().format('YYMMDDHHmmss')

    return this.run(`mongodump --uri="${uri}" --db ${dbName} --out ${backupDir}/mongo/${time}`)
  }

  /**
   * 备份静态资源
   */
  async backupStatic() {
    const { config } = this
    const { prefix, backupDir, storageDir } = config

    if (!backupDir) throw '未指定备份目录'

    // 确保目录创建
    fs.ensureDirSync(path.join(backupDir, 'static'))

    const time = dayjs().format('YYYYMMDDHHmmss')
    const file = path.join(backupDir, `static/${prefix}-static-${time}.tar.gz`) // 备份文件路径

    this.tarGz(file, storageDir)
  }

  /**
   * 备份任务
   */
  async backupTask() {
    try {
      await this.backupDatabase()
      await this.backupStatic()
    } catch (e) {
      console.error(e)
    }
  }

  /**
   * 上传备份到阿里云
   */
  async uploadOSS() {}

  /**
   * 压缩
   * @param {*} file 备份文件
   * @param {*} dir 压缩目录
   * @returns
   */
  async tarGz(file, dir) {
    const c = path.parse(dir).dir + ' ' + path.parse(dir).name

    return this.run(`tar -czvf ${file} -C ${c}`)
    // return this.run(`tar -cvf ${file} -C ${c}`)
  }

  async run(command, options) {
    let out

    try {
      console.log('options', options)
      out = await execShPromise(command, options)
    } catch (e) {
      console.log('Error: ', e)
      // console.log('Stderr: ', e.stderr)
      // console.log('Stdout: ', e.stdout)
      console.log('command', command)
      return e
    }

    // console.log('out: ', out.stdout, out.stderr)
    console.log('command', command)
  }
}

module.exports = BackupService
